package com.example.fabric_demo;


import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.StringUtils;
import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.Gateway;
import org.hyperledger.fabric.gateway.GatewayException;
import org.hyperledger.fabric.gateway.Network;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/nft")
@Slf4j
@AllArgsConstructor
public class NFTContractController {

    final Gateway gateway;

    @GetMapping("/{key}")
    public Map<String, Object> queryNFTById(@PathVariable String key) throws GatewayException {

        Map<String, Object> result = Maps.newConcurrentMap();
        Contract contract = getContract();
        byte[] cat = contract.evaluateTransaction("queryNFT", key);

        result.put("payload", StringUtils.newStringUtf8(cat));
        result.put("status", "ok");

        return result;
    }


    @GetMapping("/user/{key}")
    public Map<String, Object> findUser(@PathVariable String key) throws GatewayException {

        Map<String, Object> result = Maps.newConcurrentMap();
        Contract contract = getContract();
        byte[] cat = contract.evaluateTransaction("testFindUser", key);

        result.put("payload", StringUtils.newStringUtf8(cat));
        result.put("status", "ok");

        return result;
    }

    @PutMapping("/user/creat")
    public Map<String, Object> createUser(@RequestBody UserDTO userInfo) throws Exception {

        Map<String, Object> result = Maps.newConcurrentMap();
        Contract contract = getContract();
        byte[] bytes = contract.submitTransaction("regUser", JSON.toJSONString(userInfo));

        result.put("payload", StringUtils.newStringUtf8(bytes));
        result.put("status", "ok");
        return result;
    }

    @PutMapping("/creat")
    public Map<String, Object> createNFT(@RequestBody NFTDTO nftInfo) throws Exception {

        Map<String, Object> result = Maps.newConcurrentMap();
        Contract contract = getContract();
        byte[] bytes = contract.submitTransaction("createNFT", JSON.toJSONString(nftInfo));

        result.put("payload", StringUtils.newStringUtf8(bytes));
        result.put("status", "ok");
        return result;
    }

    @GetMapping("/transaction")
    public Map<String, Object> transactionNFT(@RequestParam("nftId")String nftId,
                                              @RequestParam("buyerId")String buyerId,
                                              @RequestParam("sellerId")String sellerId) throws Exception{
        Map<String, Object> result = Maps.newConcurrentMap();
        Contract contract = getContract();
        byte[] bytes = contract.submitTransaction("transactionNFT", nftId, buyerId, sellerId);

        result.put("payload", StringUtils.newStringUtf8(bytes));
        result.put("status", "ok");
        return result;
    }


    private Contract getContract(){
        return getNetwork().getContract("nft-contract-demo");
    }

    private Network getNetwork() {
        return gateway.getNetwork("mychannel");
    }

}
